{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Индивидуальный проект. (Кузнецов Александр Юрьевич)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1.Описание набора данных и признаков.\n",
    "\n",
    "Данный проект кредитного скоринга решает задачу предсказания вероятности успешного возврата кредита для каждого заёмщика.\n",
    "\n",
    "В анализе будут участвовать два набора данных длиной порядка 100-150 тысяч строк: исторические данные (на которых будет обучаться модель) и эталонные данные (на которых будет применена модель). \n",
    "\n",
    "Ссылка на данные https://github.com/alexander15555/alexander155\n",
    "    \n",
    "Название переменной - описание (тип переменной):\n",
    "\n",
    "1.SeriousDlqin2yrs - наблюдалась просрочка в размере 90 и более дней (Категориальная) - ЦЕЛЕВАЯ ПЕРЕМЕННАЯ\n",
    "\n",
    "2.RevolvingUtilizationOfUnsecuredLines - общий баланс по кредитным картам и личным кредитам (Процентный)\n",
    "\n",
    "3.Age - возраст заёмщика (целочисленный)\n",
    "\n",
    "4.NumberOfTime30-59DaysPastDueNotWorse - количество просрочек за последние 2 года от 30 до 59 дней (Целочисленный)\n",
    "\n",
    "5.DebtRatio - ежемесячные платежи по долгам, деленные на валовой доход в месяц (Процентный)\n",
    "\n",
    "6.MonthlyIncome - ежемесячный доход (Целочисленный)\n",
    "\n",
    "7.NumberOfOpenCreditLinesAndLoans\t- количество открытых кредитов и кредитных карт (Целочисленный)\n",
    "\n",
    "8.NumberOfTimes90DaysLate\t- количество просрочек от 90 дней и более (Целочисленный)\n",
    "\n",
    "9.NumberRealEstateLoansOrLines - количество ипотечных кредитов и кредитов на недвижимость (Целочисленный)\n",
    "\n",
    "10.NumberOfTime60-89DaysPastDueNotWorse - количество просрочек за последние 2 года от 60 до 89 дней (Целочисленный)\n",
    "\n",
    "11.NumberOfDependents - количество иждивенцев в семье, исключая себя (Целочисленный) \n",
    "\n",
    "\n",
    "С целью построения модели кредитного скоринга определяется зависимая переменная категориального типа. Это «SeriousDlqin2yrs» –  признак просроченной задолженности на 90 и более дней. В качестве независимых переменных предстают все остальные атрибуты.\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2.Первичный анализ данных."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import warnings\n",
    "warnings.simplefilter('ignore')\n",
    "\n",
    "import seaborn as sns\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import datetime as dt\n",
    "import matplotlib.pyplot as plt\n",
    "import math\n",
    "from sklearn.cross_validation import train_test_split\n",
    "from sklearn.cross_validation import KFold\n",
    "from sklearn.metrics import roc_auc_score\n",
    "from sklearn.cross_validation import cross_val_score\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.metrics import roc_curve\n",
    "import pylab as pl\n",
    "from matplotlib import pyplot\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "train = pd.read_csv('creditscore-train.csv', sep=',', encoding='cp1251')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "train.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "train.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "train.isnull().sum()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Пустые значения были обнаружены по двум атрибутам: MonthlyIncome «ежемесячный доход» и NumberOfDependents «количество иждивенцев»."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "train['MonthlyIncome'].fillna(train['MonthlyIncome'].mean(), inplace = True)\n",
    "train['NumberOfDependents'].fillna(0, inplace = True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Заменим пропущенные значения по доходу на среднее по данному признаку. \n",
    "Заменим пропущенные значения по количеству иждивенцев на нулевое значение, поскольку более вероятно, что клиент не заполнил данное поле по причине отсутствия семьи."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "train['age'].max()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Видим что в данных имеются \"выбросы\" - некорректные значения сильно отклоняющиеся от средних величин."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "train = train.drop('Unnamed: 0', axis = 1)\n",
    "train = train.rename(columns = {'NumberOfTime30-59DaysPastDueNotWorse' : 'NumberOfTime3059DaysPastDueNotWorse'})\n",
    "train = train.rename(columns = {'NumberOfTime60-89DaysPastDueNotWorse': 'NumberOfTime6089DaysPastDueNotWorse'})\n",
    "train1 = train['SeriousDlqin2yrs']\n",
    "train1 = pd.DataFrame(train1)\n",
    "train2 = train.drop('SeriousDlqin2yrs', axis = 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "RevolvingUtilizationOfUnsecuredLines = train2['RevolvingUtilizationOfUnsecuredLines']\n",
    "age = train2['age']\n",
    "NumberOfTime3059DaysPastDueNotWorse = train2['NumberOfTime3059DaysPastDueNotWorse']\n",
    "DebtRatio = train2['DebtRatio']\n",
    "MonthlyIncome = train2['MonthlyIncome']\n",
    "NumberOfOpenCreditLinesAndLoans = train2['NumberOfOpenCreditLinesAndLoans']\n",
    "NumberOfTimes90DaysLate = train2['NumberOfTimes90DaysLate']\n",
    "NumberRealEstateLoansOrLines = train2['NumberRealEstateLoansOrLines']\n",
    "NumberOfTime6089DaysPastDueNotWorse = train2['NumberOfTime6089DaysPastDueNotWorse']\n",
    "NumberOfDependents = train2['NumberOfDependents']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = [RevolvingUtilizationOfUnsecuredLines, age, NumberOfTime3059DaysPastDueNotWorse, DebtRatio, MonthlyIncome, NumberOfOpenCreditLinesAndLoans, NumberOfTimes90DaysLate, NumberRealEstateLoansOrLines, NumberOfTime6089DaysPastDueNotWorse, NumberOfDependents]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "В случае с «выбросами» использовалось правило трёх сигм. Следуя ему, вероятность того, что случайная величина отклонится от своего математического ожидания на большую величину, чем утроенное среднее квадратичное отклонение, практически равна нулю. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def outlier(col):\n",
    "    col[(col < (col.mean() - 3 * col.std())) | (col > (col.mean() + 3 * col.std()))] = col.mean()\n",
    "    return col  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "b = []\n",
    "for par in a:\n",
    "    b.append(outlier(par))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "data = pd.DataFrame(b)\n",
    "data = data.T"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 3 и 4.Первичный визуальный анализ данных и Инсайты, найденные зависимости."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Значения по каждому атрибуту исследуемого дата-сета, которые выходят за рамки, установленные вышеупомянутым правилом, были заменены на среднее по своему признаку. Ниже визуальное представление данных."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plot1 = data['RevolvingUtilizationOfUnsecuredLines'].hist(color = 'lightblue')\n",
    "plot1.set_title(\"Revolving Utilization Of Unsecured Lines\")\n",
    "pl.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plot1 = data['age'].hist(color = 'lightblue')\n",
    "plot1.set_title(\"AGE\")\n",
    "pl.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plot1 = data['NumberOfTime3059DaysPastDueNotWorse'].hist(color = 'lightblue')\n",
    "plot1.set_title(\"Number Of Time 30-59 Days Past Due Not Worse\")\n",
    "pl.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plot1 = data['DebtRatio'].hist(color = 'lightblue')\n",
    "plot1.set_title(\"Debt Ratio\")\n",
    "pl.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plot1 = data['MonthlyIncome'].hist(color = 'lightblue')\n",
    "plot1.set_title(\"Monthly Income\")\n",
    "pl.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plot1 = data['NumberOfOpenCreditLinesAndLoans'].hist(color = 'lightblue')\n",
    "plot1.set_title(\"Number Of Open Credit Lines And Loans\")\n",
    "pl.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plot1 = data['NumberOfTimes90DaysLate'].hist(color = 'lightblue')\n",
    "plot1.set_title(\"Number Of Times 90 Days Late\")\n",
    "pl.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plot1 = data['NumberRealEstateLoansOrLines'].hist(color = 'lightblue')\n",
    "plot1.set_title(\"Number Real Estate Loans Or Lines\")\n",
    "pl.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plot1 = data['NumberOfTime6089DaysPastDueNotWorse'].hist(color = 'lightblue')\n",
    "plot1.set_title(\"Number Of Time 60-89 Days Past Due Not Worse\")\n",
    "pl.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plot1 = data['NumberOfDependents'].hist(color = 'lightblue')\n",
    "plot1.set_title(\"Number Of Dependents\")\n",
    "pl.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Резкие \"выбросы\" в данных не наблюдаются.Средний возраст заемщиков около 55 лет."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "cols = ['RevolvingUtilizationOfUnsecuredLines', 'age',\n",
    "       'NumberOfTime3059DaysPastDueNotWorse', 'DebtRatio', 'MonthlyIncome',\n",
    "       'NumberOfOpenCreditLinesAndLoans', 'NumberOfTimes90DaysLate',\n",
    "       'NumberRealEstateLoansOrLines', 'NumberOfTime6089DaysPastDueNotWorse',\n",
    "       'NumberOfDependents']\n",
    "a4_dims = (12, 8)\n",
    "df = data[cols].corr()\n",
    "fig, ax = pyplot.subplots(figsize=a4_dims)\n",
    "sns.heatmap(ax=ax, data=df)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Наблюдается корреляция между признаками \"NumberRealEstateLoansOrLines\" (Количество ипотечных кредитов и кредитов на недвижимость, включая кредитные линии собственного капитала) и \"NumberOfOpenCreditLinesAndLoans\" (Количество открытых кредитов и кредитных карт).\n",
    "\n",
    "Также наблюдаетcя более слабая корреляция между признаками:\n",
    "1. \"NumberOfTimes90DaysLate\" (количество просрочек от 90 дней и более) и \"NumberOfTime6089DaysPastDueNotWorse\" (количество просрочек за последние 2 года от 60 до 89 дней).\n",
    "2. \"NumberOfTime6089DaysPastDueNotWorse\" (количество просрочек за последние 2 года от 60 до 89 дней) и \"NumberOfTime3059DaysPastDueNotWorse\" (Количество просрочек за последние 2 года от 30 до 59 дней)\n",
    "3. \"NumberRealEstateLoansOrLines\" (Количество ипотечных кредитов и кредитов на недвижимость, включая кредитные линии собственного капитала) и \"MonthlyIncome\" (Ежемесячный доход)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.pairplot(data[['NumberOfOpenCreditLinesAndLoans','NumberRealEstateLoansOrLines',\n",
    "                   'NumberOfTime6089DaysPastDueNotWorse','NumberOfTimes90DaysLate',\n",
    "                   'NumberOfTime3059DaysPastDueNotWorse','MonthlyIncome']])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 5. Выбор метрики"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "В качестве основной метрики для оценки качества модели будет выбран критерий ROC-AUC. Метрика ROC AUC зависит не от строгой дискретной классификации,а от предсказанных вероятностей классов, поэтому она более применима к задаче такого типа. При этом она подходит для несбалансированных данных.\n",
    "\n",
    "ROC-кривая – это графическая характеристика качества бинарного классификатора, отражает зависимость количества верно классифицированных положительных примеров от количества неверно классифицированных отрицательных примеров. AUC является количественным показателем ROC: это площадь, ограниченная осями и ROC-кривой.\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 6. Выбор модели"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Выбор модели - логистическая регрессия. \n",
    "\n",
    "Простой и быстрый вариант.Логистическая регрессия выдает вероятности отнесения к разным классам (это очень ценится в кредитном скоринге). Также логистическая регрессия хорошо интерпретируема и используется в реальном банковском моделировании рисков. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 7. Предобработка данных"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Предобработка данных для данной работы была проведена в пунктах ранее.\n",
    "\n",
    "Первичная обработка данных представляет из себя замену пустых значений и избавление от «выбросов». Пустые значения на данных для обучения были обнаружены по двум атрибутам: «ежемесячный доход» и «количество иждивенцев». Было принято решение заменить пропущенные значения по доходу на среднее по данному признаку. А по количеству иждивенцев – на нулевое значение, поскольку более вероятно, что клиент не заполнил данное поле по причине отсутствия семьи. В случае с «выбросами» использовалось правило трёх сигм. Следуя ему, вероятность того, что случайная величина отклонится от своего математического ожидания на большую величину, чем утроенное среднее квадратичное отклонение, практически равна нулю."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 8,9,10. Кросс-валидация и настройка гиперпараметров модели, создание новых признаков и описание этого процесса, построение кривых валидации и обучения"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "X = data\n",
    "Y = train1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "X.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Y.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "kf = KFold(n=150000, n_folds=5, shuffle=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Используемые для формирования модели информационные данные являются исторической выборкой, которая наиболее точно отображает генеральную совокупность исследуемых людей. Её разбиение проводилось при помощи техники кросс-валидации по 5 блокам с использованием генератора разбиений KFold.\n",
    "\n",
    "Предобработка данных и признаков производилась в пункта ранее."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def my_scorer(estimator, testX, testY):\n",
    "    predicted_testY = estimator.predict_proba(testX)[:, 1]\n",
    "    return roc_auc_score(testY, predicted_testY)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "scaler = StandardScaler()\n",
    "scaledX = scaler.fit_transform(X)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Перед разбиением производилось случайное перемешивание объектов выборки, чтобы избежать смещённости кросс-валидационной оценки. Реализация логистической регрессии показала, что наибольшая AUC-ROC величина наблюдалась при значении свободного члена С = 0,0001. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def LogR_teach(C_value):\n",
    "    clf = LogisticRegression(penalty='l2', C=C_value)\n",
    "    return cross_val_score(clf, scaledX, Y, cv=kf, scoring=my_scorer).mean()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def C_variants():\n",
    "    for power in range(-4, 2):\n",
    "        C = math.pow(10, power)\n",
    "        quality = LogR_teach(C)\n",
    "        print ('C=', C, ', quality=', quality)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "C_variants()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_train, X_test, y_train, y_test = train_test_split(scaledX, Y, test_size=.2, random_state=0)\n",
    "clf = LogisticRegression(penalty='l2', C=0.0001)\n",
    "clf.fit(X_train, y_train)\n",
    "y_score = clf.predict_proba(X_test)[:, 1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plt.figure()\n",
    "line_width = 1\n",
    "fpr, tpr, thresholds = roc_curve(y_test, y_score)\n",
    "plt.plot(fpr, tpr, color='navy', lw=line_width, label='LogRegression, C=0.0001')\n",
    "plt.plot([0, 1], [0, 1], color='lightblue', lw=line_width, linestyle='--')\n",
    "plt.xlim([0.0, 1.0])\n",
    "plt.ylim([0.0, 1.0])\n",
    "plt.xlabel('False Positive Rate')\n",
    "plt.ylabel('True Positive Rate')\n",
    "plt.title('ROC curve')\n",
    "plt.legend(loc=\"lower right\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Показателем качества модели является величина площади под ROC-кривой 0,817."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 11. Прогноз для тестовой или отложенной выборки"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Приведем отложенный датасет к надлежащему виду, повторив все преобразования. Затем применим логистическую регрессию и вычислим предсказания на тестовом дата-сете."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test = pd.read_csv('creditscore-test.csv', sep=',', encoding='cp1251')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test.isnull().sum()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Пустые значения были обнаружены по двум атрибутам: MonthlyIncome «ежемесячный доход» и NumberOfDependents «количество иждивенцев»."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test['MonthlyIncome'].fillna(test['MonthlyIncome'].mean(), inplace = True)\n",
    "test['NumberOfDependents'].fillna(0, inplace = True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Заменим пропущенные значения по доходу на среднее по данному признаку. Заменим пропущенные значения по количеству иждивенцев на нулевое значение, поскольку более вероятно, что клиент не заполнил данное поле по причине отсутствия семьи."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "del test['Unnamed: 0']\n",
    "del test['SeriousDlqin2yrs']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test = test.rename(columns = {'NumberOfTime30-59DaysPastDueNotWorse' : 'NumberOfTime3059DaysPastDueNotWorse'})\n",
    "test = test.rename(columns = {'NumberOfTime60-89DaysPastDueNotWorse': 'NumberOfTime6089DaysPastDueNotWorse'})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "RevolvingUtilizationOfUnsecuredLines = test['RevolvingUtilizationOfUnsecuredLines']\n",
    "age = test['age']\n",
    "NumberOfTime3059DaysPastDueNotWorse = test['NumberOfTime3059DaysPastDueNotWorse']\n",
    "DebtRatio = test['DebtRatio']\n",
    "MonthlyIncome = test['MonthlyIncome']\n",
    "NumberOfOpenCreditLinesAndLoans = test['NumberOfOpenCreditLinesAndLoans']\n",
    "NumberOfTimes90DaysLate = test['NumberOfTimes90DaysLate']\n",
    "NumberRealEstateLoansOrLines = test['NumberRealEstateLoansOrLines']\n",
    "NumberOfTime6089DaysPastDueNotWorse = test['NumberOfTime6089DaysPastDueNotWorse']\n",
    "NumberOfDependents = test['NumberOfDependents']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "c = [RevolvingUtilizationOfUnsecuredLines, age, NumberOfTime3059DaysPastDueNotWorse, DebtRatio, MonthlyIncome, NumberOfOpenCreditLinesAndLoans, NumberOfTimes90DaysLate, NumberRealEstateLoansOrLines, NumberOfTime6089DaysPastDueNotWorse, NumberOfDependents]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "d = []\n",
    "for par in c:\n",
    "    d.append(outlier(par))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_ = pd.DataFrame(d)\n",
    "test_ = test_.T"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "scaled_test = scaler.transform(test_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "clf = LogisticRegression(penalty='l2', C=0.0001)\n",
    "clf.fit(scaledX, Y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Применяется модель логистической регрессии с наиболее подходящим коэффициентом С = 0,0001."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "prediction = clf.predict_proba(scaled_test)[:, 1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "min(prediction), max(prediction)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "result = pd.DataFrame(np.array(prediction), columns=['probability'], index=test_.index)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "result[result['probability']>0.5].count()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "result.count()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Тоесть доля заёмщиков, у которых предсказанная вероятность больше 0,5 составляет чуть более 1,5 % от общего количества людей в тестовой выборке. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "result"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 12. Выводы"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Была построена модель для кредитного скоринга, которая решает задачу предсказания вероятности успешного возврата кредита для каждого заёмщика.\n",
    "\n",
    "На исторических данных полученное качество модели, оцененное с поомщью метрики ROC-AUС составляет 0.817, что говорит о хорошей предсказательной способности модели.\n",
    "\n",
    "На тестовой выборке были получены предсказанные вероятности, определяющие кредитоспособность клиентов. Доля заёмщиков, у которых предсказанная вероятность больше 0,5 составляет чуть более 1,5 % от общего количества людей в тестовой выборке.\n",
    "\n",
    "Улучшить модель возможно, если:\n",
    "1.более точно отбрать важные для модели признаки\n",
    "2.использовать дополнительно внешние данные\n",
    "3.определить ошибки алгоритма и скорректировать модель."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
